﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kale.Core.Security;

namespace Kale.Db.Sql
{
   public partial class User : IUser
   {
      private ISecurityProvider _provider;
      private bool _loadedExplicitRoles = false;
      private bool _loadedEffectiveRoles = false;
      private bool _loadedExplicitGroups = false;
      private bool _loadedEffectiveGroups = false;

      private List<IUserRole> _explicitRoles = new List<IUserRole>();
      private List<IUserRole> _effectiveRoles = new List<IUserRole>();
      private List<IUserGroup> _explicitGroups = new List<IUserGroup>();
      private List<IUserGroup> _effectiveGroups = new List<IUserGroup>();

      internal ISecurityProvider Provider
      {
         get { return _provider; }
         set { _provider = value; }
      }

      #region IUser Members

      DateTime? IUser.LastLogin
      {
         get { return this.LastLogin; }
      }

      #endregion

      #region ISecurityPrincipal Members

      Guid ISecurityPrincipal.Uid
      {
         get { return this.Uid; }
      }

      string ISecurityPrincipal.Name
      {
         get { return this.Name; }
      }

      #endregion

      #region ISecurityMember Members

      IUserRole[] ISecurityMember.ExplicitRoles
      {
         get 
         {
            if (!_loadedExplicitRoles)
            {
               lock (_explicitRoles)
               {
                  _explicitRoles.Clear();
                  foreach (IUserRole role in _provider.GetUserRolesForUser(Uid))
                  {
                     _explicitRoles.Add(role);
                  }

                  _loadedExplicitRoles = true;
               }
            }

            return _explicitRoles.ToArray();
         }
      }

      IUserRole[] ISecurityMember.EffectiveRoles
      {
         get 
         {
            if (!_loadedEffectiveRoles)
            {
               lock (_effectiveRoles)
               {
                  _effectiveRoles.Clear();

                  SecurityLoader.LoadEffectiveRoles(this as ISecurityMember, _effectiveRoles);

                  _loadedEffectiveRoles = true;
               }
            }

            return _effectiveRoles.ToArray();
         }
      }

      IUserGroup[] ISecurityMember.ExplicitUserGroups
      {
         get 
         {
            if (!_loadedExplicitGroups)
            {
               lock (_explicitGroups)
               {
                  _explicitGroups.Clear();

                  foreach (IUserGroup group in _provider.GetUserGroupsForUser(Uid))
                  {
                     _explicitGroups.Add(group);
                  }

                  _loadedExplicitGroups = true;
               }
            }

            return _explicitGroups.ToArray();
         }
      }

      IUserGroup[] ISecurityMember.EffectiveUserGroups
      {
         get
         {
            if (!_loadedEffectiveGroups)
            {
               lock (_effectiveGroups)
               {
                  _effectiveGroups.Clear();

                  SecurityLoader.LoadEffectiveGroups(this as ISecurityMember, _effectiveGroups);

                  _loadedEffectiveGroups = true;
               }
            }

            return _explicitGroups.ToArray();
         }
      }

      #endregion
   }
}
